package com.zenchn.aliyun.oss.api.impl;


import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.zenchn.aliyun.oss.api.OssDownloadService;
import com.zenchn.aliyun.oss.utils.OssCommonUtils;
import com.zenchn.entity.JsonResult;
import com.zenchn.utils.CommonUtils;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 文件下载实现类
 * @author dingxinfa
 * @date 2018-08-16
 *
 */
@Service
public class OssDownloadServiceImpl implements OssDownloadService {
	/**
	 * 简单下载
	 */
	@Override
	public JsonResult<Object> simplyDownloadToLocalFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, String localFilePath){
		JsonResult<Object> jsonResult=new JsonResult<Object>();
		jsonResult.setSuccess(false);
		jsonResult.setCode(0);

		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);
		try{
			// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
			ObjectMetadata  objectMetadata= ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFilePath));

			//md5 值比较
			String md5ByFile = CommonUtils.md5HexByFile(localFilePath);
			if(objectMetadata.getETag().equalsIgnoreCase(md5ByFile)){
				jsonResult.setSuccess(true);
				jsonResult.setCode(1);
				jsonResult.setData(localFilePath);
			}else{
				File localFile=new File(localFilePath);
				if(localFile.exists()){
					localFile.delete();
				}
			}
			ossClient.shutdown();

		} catch (OSSException oe) {
			jsonResult.setData(OssCommonUtils.extractOSSException(oe));
		} catch (ClientException ce) {
			jsonResult.setData(OssCommonUtils.extractClientException(ce));
		} finally {
			//关闭客服端释放资源
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}



		return jsonResult;
	}






    /**
	 * 简单下载
	 */
	@Override
	public JsonResult<Object> simplyDownload(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName){
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);
		JsonResult<Object> jsonResult=new JsonResult<Object>();
		jsonResult.setSuccess(false);
		jsonResult.setCode(0);
		try{
			// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
			OSSObject ossObject = ossClient.getObject(bucketName, objectName);
			// 读取文件内容
			BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent()));

			StringBuilder stringBufferline=new StringBuilder();
			while (true) {
				String line = reader.readLine();
				if (line == null){
					break;
				}
				stringBufferline.append(line);

			}
			// 数据读取完成后，获取的流必须关闭，否则会造成连接泄漏，导致请求无连接可用，程序无法正常工作。
			reader.close();
			//关闭OSSClient。
			ossClient.shutdown();

			if (stringBufferline.length() > 0) {
				jsonResult.setSuccess(true);
				jsonResult.setCode(1);
				jsonResult.setData(stringBufferline.toString());
			}

		} catch (OSSException oe) {
			jsonResult.setData(OssCommonUtils.extractOSSException(oe));
		} catch (ClientException ce) {
			jsonResult.setData(OssCommonUtils.extractClientException(ce));
		} catch (IOException e) {
			jsonResult.setData(OssCommonUtils.extractIOException(e));
		} finally {
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}

		return jsonResult;


	}
	
	/**
	 * 分片下载(断点续传下载)
	 * @throws Throwable 
	 */
	@Override
	public JsonResult<Object> multipartDownloadToLocalFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, String localFilePath){
		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);
		JsonResult<Object> jsonResult=new JsonResult<Object>();
		jsonResult.setSuccess(false);
		jsonResult.setCode(0);
		try {

			String checkpointFile=localFilePath+".log";

			// 创建OSSClient实例。
			// 下载请求，10个任务并发下载，启动断点续传。
			DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, objectName);
			downloadFileRequest.setDownloadFile(localFilePath);
			downloadFileRequest.setPartSize(1024 * 1024);
			downloadFileRequest.setTaskNum(10);
			downloadFileRequest.setEnableCheckpoint(true);
			downloadFileRequest.setCheckpointFile(checkpointFile);
			// 下载文件。
			DownloadFileResult downloadRes = ossClient.downloadFile(downloadFileRequest);
			// 下载成功时，会返回文件元信息。
			ObjectMetadata  objectMetadata=downloadRes.getObjectMetadata();
			
			jsonResult.setSuccess(true);
			jsonResult.setCode(1);
			jsonResult.setData(localFilePath);

			ossClient.shutdown();
		} catch (OSSException oe) {
			jsonResult.setData(OssCommonUtils.extractOSSException(oe));
		} catch (ClientException ce) {
			jsonResult.setData(OssCommonUtils.extractClientException(ce));
		} catch (Throwable throwable) {
			jsonResult.setData(OssCommonUtils.extractThrowable(throwable));
		} finally {
			//关闭客服端释放资源
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}
		return jsonResult;
	}


	/**
	 * 加工处理图片下载到本地文件
	 */
	@Override
	public JsonResult<Object> processImageDownloadToLocalFile(String endpoint, String accessKeyId, String accessKeySecret, String bucketName, String objectName, String processStyle, String localFilePath){
		JsonResult<Object> jsonResult=new JsonResult<Object>();
		jsonResult.setSuccess(false);
		jsonResult.setCode(0);

		OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId,accessKeySecret);
		try{
			GetObjectRequest request = new GetObjectRequest(bucketName, objectName);
			request.setProcess(processStyle);

			// 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
			ObjectMetadata  objectMetadata= ossClient.getObject(request, new File(localFilePath));

			//md5 值比较
			jsonResult.setSuccess(true);
			jsonResult.setCode(1);
			jsonResult.setData(localFilePath);

			ossClient.shutdown();

		} catch (OSSException oe) {
			jsonResult.setData(OssCommonUtils.extractOSSException(oe));
		} catch (ClientException ce) {
			jsonResult.setData(OssCommonUtils.extractClientException(ce));
		} finally {
			//关闭客服端释放资源
			if (ossClient != null) {
				ossClient.shutdown();
			}
		}
		return jsonResult;
	}
}
